package com.sun.gis.tools.wmts;

import org.geotools.referencing.crs.DefaultGeographicCRS;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.gis.tools.sld.SldRenderer;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.MapContent;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.Style;
import org.geotools.swing.JMapFrame;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

/**
 * @author sunbt
 * @date 2023/10/7 0:42
 */
public class GeoJsonLoader {

    public static SimpleFeatureCollection geometryToFeatureCollection(Geometry geometry) {
        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setName("GeoJsonGeometry");
        typeBuilder.setCRS(DefaultGeographicCRS.WGS84); // 设置坐标参考系统
        typeBuilder.add("the_geom", geometry.getClass());

        SimpleFeatureType featureType = typeBuilder.buildFeatureType();
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
        featureBuilder.add(geometry);

        SimpleFeature feature = featureBuilder.buildFeature(null); // null for feature ID
        DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
        featureCollection.add(feature);

        return featureCollection;
    }


    /**
     * 将地图视图渲染到PNG图像文件。
     *
     * @param mapContent mapContent：要渲染的地图内容。
     * @param bound      bound：要渲染的区域的边界。
     * @param photoPath  photoPath：输出PNG将保存的文件路径。
     */
    public static void rendererToPng(MapContent mapContent, ReferencedEnvelope bound, String photoPath) {

        try {
            // 初始化一个新的渲染器并设置其地图内容
            StreamingRenderer renderer = new StreamingRenderer();
            renderer.setMapContent(mapContent);

            // 定义输出图像的尺寸
            int imageWidth = 1024;
            int imageHeight = 1024;
            BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
            Graphics2D graphics = image.createGraphics();

            // 将图像背景设置为透明
            graphics.setComposite(AlphaComposite.Clear);
            graphics.fillRect(0, 0, imageWidth, imageHeight);
            graphics.setComposite(AlphaComposite.SrcOver);

            // 在图像上渲染地图
            Rectangle imageBounds = new Rectangle(0, 0, imageWidth, imageHeight);
            renderer.paint(graphics, imageBounds, bound);

            // 将渲染的图像保存为PNG文件
            File pngFile = new File(photoPath);
            ImageIO.write(image, "png", pngFile);

            System.out.println("输出文件: " + pngFile.getAbsolutePath());
        } catch (Exception e) {
            // 在渲染过程中处理可能出现的任何异常
            e.printStackTrace();
        }
    }


    public static Geometry geoJsonToGeometry(String geoJsonStr) throws ParseException {
        JSONObject jsonObject = JSON.parseObject(geoJsonStr);
        JSONArray coordinates = jsonObject.getJSONArray("coordinates").getJSONArray(0);
        StringBuilder wkt = new StringBuilder("POLYGON((");

        for (int i = 0; i < coordinates.size(); i++) {
            JSONArray point = coordinates.getJSONArray(i);
            wkt.append(point.getDouble(0)).append(" ").append(point.getDouble(1)).append(",");
        }
        wkt.deleteCharAt(wkt.length() - 1);
        wkt.append("))");

        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        WKTReader reader = new WKTReader(geometryFactory);
        return reader.read(wkt.toString());
    }

    public static void test() {
        String geoJsonStr =  "{\n" +
                "        \"coordinates\": [\n" +
                "          [\n" +
                "            [\n" +
                "              120.49260317333017,\n" +
                "              31.619643076821475\n" +
                "            ],\n" +
                "            [\n" +
                "              120.49269519023414,\n" +
                "              31.61621942444208\n" +
                "            ],\n" +
                "            [\n" +
                "              120.49670146764805,\n" +
                "              31.616339977720642\n" +
                "            ],\n" +
                "            [\n" +
                "              120.49655282484696,\n" +
                "              31.619727461000494\n" +
                "            ],\n" +
                "            [\n" +
                "              120.49260317333017,\n" +
                "              31.619643076821475\n" +
                "            ]\n" +
                "          ]\n" +
                "        ],\n" +
                "        \"type\": \"Polygon\"\n" +
                "      }";

        // SLD (样式图层描述符) 文件的路径
        String path = "E:\\code\\gitee\\gis-server\\data\\sld\\polygon1.sld";

        // 从SLD文件加载样式
        Style style = SldRenderer.readSldReturnOne(path);

        // 这是根据获取的wmts切片计算出来的
        ReferencedEnvelope bound = new ReferencedEnvelope(120.4925537109375, 120.498046875, 31.615965936476076, 31.620643692450574, DefaultGeographicCRS.WGS84);

        try {
            Geometry geometry = geoJsonToGeometry(geoJsonStr);
            SimpleFeatureCollection featureCollection = geometryToFeatureCollection(geometry);
            MapContent mapContent = new MapContent();


            FeatureLayer layer = new FeatureLayer(featureCollection, style);
            mapContent.addLayer(layer);

            ReferencedEnvelope bounds = featureCollection.getBounds();
            mapContent.getViewport().setBounds(bound);

            // 使用JMapFrame在屏幕上显示地图
            JMapFrame.showMap(mapContent);


            // 输出图像 (PNG) 的路径
            String photoPath = "E:\\code\\gitee\\gis-server\\data\\output\\wmts\\wmts\\geojson.png";
            rendererToPng(mapContent, bound, photoPath);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void mergeTwoImages(String imagePath1, String imagePath2, String outputPath) {
        try {
            // 读取两个图片
            BufferedImage image1 = ImageIO.read(new File(imagePath1));
            BufferedImage image2 = ImageIO.read(new File(imagePath2));

            // 假设两张图片尺寸相同
            int width = image1.getWidth();
            int height = image1.getHeight();

            // 创建一个新的BufferedImage，用于存放叠加后的图像
            BufferedImage mergedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

            // 画出两个图像
            Graphics2D g = mergedImage.createGraphics();
            g.drawImage(image1, 0, 0, null);
            g.drawImage(image2, 0, 0, null);
            g.dispose();

            // 将叠加后的图像保存为新文件
            ImageIO.write(mergedImage, "PNG", new File(outputPath));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
//        test();
        String imagePath2 = "E:\\code\\gitee\\gis-server\\data\\output\\wmts\\wmts\\geojson.png";
        String imagePath1 = "E:\\code\\gitee\\gis-server\\data\\output\\wmts\\wmts\\montage.png";
        String outputPath = "E:\\code\\gitee\\gis-server\\data\\output\\wmts\\wmts\\new.png";

        mergeTwoImages(imagePath1, imagePath2, outputPath);
    }

}
